home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / scope / 001-025 / scopedisk14 / c64em / main.c < prev    next >
C/C++ Source or Header  |  1995-03-18  |  7KB  |  373 lines

  1. /*
  2.  *        Commodore 64 Spoof Emulator (C) Eddy Carroll, 1st April 1988
  3.  *
  4.  * Module: MAIN.C
  5.  *
  6.  * This module is the mainline - it handles the input loop and command
  7.  * interpretation logic.
  8.  *
  9.  * Note: Compile with Lattice V3.10 or later. Manx may work, but hasn't
  10.  * been tested.
  11.  *
  12.  */
  13.  
  14. #include <exec/types.h>
  15. #include <exec/io.h>
  16. #include <intuition/intuition.h>
  17. #include "screen.h"
  18. #include "commands.h"
  19.  
  20. extern struct Menu mymenus;
  21. extern struct IntuiText mytext[];
  22.  
  23. extern struct commandlist command[];    /* Commands & Responses */
  24. extern char *errormsg[];                /* List of error msgs    */
  25. extern int  MAXCOMMANDS;                /* Number of commands    */
  26. extern int  MAXERRORS;                    /* Number of messages    */
  27. extern char *STARTUP;                    /* Startup message        */
  28. extern char *ABOUT;                        /* "About..." message    */
  29. extern char *READY;                        /* Ready prompt            */
  30.  
  31. /*
  32.  * Executes one of the menu commands
  33.  *
  34.  */
  35.  
  36. void domenu(opt)
  37. int opt;
  38. {
  39.     CURSOROFF;
  40.  
  41.     switch (opt) {
  42.  
  43.     case M_ABOUT:
  44.         clearscreen();
  45.         if (titlebar) printchar('\r'); /* Skip past title bar if on */
  46.         printmess(ABOUT);
  47.         printmess(READY);
  48.         break;
  49.  
  50.     case M_TITLE:
  51.         titlebar = !titlebar;
  52.         ClearMenuStrip(mywin);
  53.         mytext[1].IText = titlebar ? " Hide Title" : " Show Title";
  54.         SetMenuStrip(mywin,&mymenus);
  55.         ShowTitle(myscreen, titlebar);
  56.         break;
  57.  
  58.     case M_QUIT:
  59.         cleanup(0);
  60.         break;
  61.  
  62.     }
  63. }
  64.  
  65. /*
  66.  * Returns a random number in range 0..range-1.
  67.  *
  68.  */
  69.  
  70. int random(range)
  71. int range;
  72. {
  73.     LONG seconds,micros;
  74.     CurrentTime(&seconds,µs);
  75.     return (micros % range);
  76. }
  77.  
  78.  
  79. /*
  80.  * Reads current line from screen into string, stripping off any extra
  81.  * leading or trailing spaces.
  82.  *
  83.  */
  84.  
  85. void getcommand(s)
  86. char *s;
  87. {
  88.     int i = 0, j = 39;
  89.     char *p; 
  90.     p = screen[cursory];
  91.     while (p[i] == ' ' && i < 40)
  92.         i++;
  93.     if (i == 40) {
  94.         *s = '\0';
  95.         return;
  96.     } 
  97.  
  98.     while (p[j] == ' ')
  99.         j--;
  100.     while (i <= j) {
  101.         *s++ = toupper(p[i]);
  102.         i++;
  103.     }
  104.     *s = '\0';
  105. }
  106.  
  107.  
  108. /*
  109.  * Returns TRUE if the first n chars of the two strings are equal, else
  110.  * returns FALSE
  111.  *
  112.  */
  113.  
  114. int match(s1,s2,n)
  115. char *s1,*s2;
  116. int n;
  117. {
  118.     while (*s1++ == *s2++ && n)
  119.         n--;
  120.     return (!n);
  121. }
  122.  
  123.  
  124. /*
  125.  * Initialises error messages to be in random order.
  126.  *
  127.  */
  128.  
  129. void initerror()
  130. {
  131.     int i, x, y;
  132.     char *p;
  133.  
  134.     for (i = 0; i < MAXERRORS; i++) {
  135.         x = random(MAXERRORS);
  136.         y = MAXERRORS - 1 - random(MAXERRORS);
  137.         p = errormsg[x];
  138.         errormsg[x] = errormsg[y];
  139.         errormsg[y] = p;
  140.     }
  141. }
  142.  
  143.  
  144. /*
  145.  * Prints a suitable response for command in string s. If a match is found
  146.  * in the command list, then a reponse appropriate to that command is
  147.  * printed, else one of the standard error messages is printed.
  148.  *
  149.  */
  150.  
  151. void docommand(s)
  152. char *s;
  153. {
  154.     static int curerr = 0;
  155.     int i = 1, k = -1, x, y;
  156.     char *p;
  157.     struct commandlist *com;
  158.  
  159.     if (*s >= '0' && *s <= '9')
  160.         k = 0;
  161.     else {
  162.         while (i < MAXCOMMANDS && k < 0) {
  163.             if (match(command[i].asc,s,command[i].len))
  164.                 k = i; 
  165.             i++;
  166.         }
  167.     }
  168.  
  169.     printchar('\r');
  170.     if (k >= 0) {
  171.         com = &command[k];
  172.         do {
  173.             com->num++;
  174.  
  175.             /* If we have printed all three messages once each, re-arrange    */
  176.             /* the order of them before we print them again to make it        */
  177.             /* seem random.                                                    */
  178.  
  179.             if (com->num >= MAXRESPONSE) {
  180.                 com->num = 0;
  181.                 x = random(MAXRESPONSE); y = random(MAXRESPONSE);
  182.                 p = com->response[x];
  183.                 com->response[x] = com->response[y];
  184.                 com->response[y] = p;
  185.             }
  186.         } while ((p = com->response[com->num]) == NULL);
  187.         printmess(p);
  188.     } else {
  189.         printmess(errormsg[curerr]);
  190.         curerr++;
  191.         if (curerr >= MAXERRORS) {
  192.             curerr = 0;
  193.             initerror();
  194.         }
  195.     }
  196.  
  197.     printmess(READY);
  198. }
  199.  
  200.  
  201. /*
  202.  * Initialises the message headers to point to random messages
  203.  *
  204.  */
  205.  
  206. void initmess()
  207. {
  208.     int i;
  209.     for (i = 0; i < MAXCOMMANDS; i++)
  210.         command[i].num = random(3);
  211. }
  212.  
  213.  
  214. /*
  215.  * Returns code for function key n, where n = 0..20
  216.  * Returns 0 if no char equivalent.
  217.  *
  218.  */
  219.  
  220. char fkey(n)
  221. int n;
  222. {
  223.     register char ch;
  224.     switch (n) {
  225.  
  226.     case 0:        ch = C_HOME;    break;
  227.     case 1:        ch = C_CLEAR;    break;
  228.     case 9:        ch = C_INSERT;    break;
  229.  
  230.     case 20:     printmess("HELP");
  231.     default: ch = 0;        break;
  232.  
  233.     }
  234.     return (ch);
  235. }
  236.  
  237. /*
  238.  * Converts code (an escape character) into one of the internal codes
  239.  * (or 0 if no corresponding code)
  240.  *
  241.  */
  242.  
  243. char convert(ch)
  244. char ch;
  245. {
  246.     switch (ch) {
  247.  
  248.     case 'A': ch = C_UP;        break;
  249.     case 'B': ch = C_DOWN;        break;
  250.     case 'C': ch = C_RIGHT;        break;
  251.     case 'D': ch = C_LEFT;        break;
  252.  
  253.     default:  ch = 0;
  254.     }
  255.  
  256.     return(ch);
  257. }
  258.  
  259. /*
  260.  * Mainline
  261.  *
  262.  */
  263.  
  264. void main()
  265. {
  266.     LONG MenuNumber;
  267.     struct MenuItem *item;
  268.     register struct IntuiMessage *message;
  269.     register struct Message *conmessage;
  270.     int escape = 0;
  271.     LONG class;
  272.     USHORT code;
  273.     int time = 3, curstate = 0, fkeynum;
  274.     char s[50], ch;
  275.  
  276.  
  277.     titlebar = 0;    /* Initially hidden */
  278.     initscreen();
  279.     initmess();
  280.     initerror();
  281.     printmess(STARTUP);
  282.     printmess(READY);
  283.     CURSORON;
  284.  
  285.  
  286.     /* Main loop */
  287.  
  288. #define INTUIBITS    (1 << mywin->UserPort->mp_SigBit)
  289. #define CONSOLEBITS    (1 << ConReadPort->mp_SigBit)
  290.  
  291.     while (1) {
  292.  
  293.         /* Reset message pointers, just in case 2nd part of conditional */
  294.         /* && isn't executed. */
  295.         message    = NULL;
  296.         conmessage = NULL;
  297.  
  298.         while ((message = (struct IntuiMessage *)
  299.                     GetMsg(mywin->UserPort)) == NULL &&
  300.                 (conmessage = (struct Message *)
  301.                     GetMsg(ConReadPort)) == NULL)
  302.             Wait ( INTUIBITS | CONSOLEBITS);
  303.  
  304.  
  305.         if (message) {        /* Got an IntuiMessage */
  306.             class = message->Class;
  307.             code = message->Code;
  308.             ReplyMsg((struct Message *)message);
  309.  
  310.             switch (class) {
  311.  
  312.             case MENUPICK:
  313.                 MenuNumber = code;
  314.                 while (MenuNumber != MENUNULL) {
  315.                     item = (struct MenuItem *)ItemAddress(&mymenus,MenuNumber);
  316.                     code = item->Command;
  317.                     MenuNumber = item->NextSelect;
  318.                 }
  319.                 domenu(code);
  320.                 break;
  321.  
  322.             case INTUITICKS:
  323.                 if (time == 0) {
  324.                     curstate = 1 - curstate;
  325.                     if (curstate)
  326.                         CURSORON;
  327.                     else
  328.                         CURSOROFF;
  329.                     time = 3;
  330.                 } else --time;
  331.                 break;
  332.  
  333.             }
  334.         }
  335.  
  336.         if (conmessage) {        /* Character from console */
  337.             ch = *constring;
  338.             /* Retrieve char, then line up request for next char */
  339.             QueueRead(ConReadReq,constring);
  340.             if (ch == CSI)
  341.                 escape = 1, fkeynum = 0;
  342.             else {
  343.                 if (escape) {
  344.                     if (isdigit(ch))
  345.                         fkeynum = fkeynum * 10 + ch - '0', ch = 0;
  346.                     else if (ch == '?')
  347.                         fkeynum = 20, ch = 0;
  348.                     else if (ch == ' ')
  349.                         escape = 2, ch = 0;
  350.                     else {
  351.                         escape = 0;
  352.                         if (ch == '~')
  353.                             ch = fkey(fkeynum);
  354.                         else if (escape != 2)
  355.                             ch = convert(ch);
  356.                     }
  357.                 }
  358.                 CURSOROFF;
  359.                 if (ch == '\r') {
  360.                     getcommand(s);    /* Read command from screen */
  361.                     printchar(ch);
  362.                     if (*s)
  363.                         docommand(s);
  364.                 } else
  365.                     printchar(ch);
  366.                 CURSORON;
  367.                 time = 3;
  368.                 curstate = 1;
  369.             }
  370.         }
  371.     }
  372. }
  373.